﻿using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;

namespace PedesTrainProject.Grid
{
    [Serializable()]
    public class Road : ISerializable
    {
        private List<CarLight> carLights;
        private List<PedestrianLight> pedestrianLights = new List<PedestrianLight>();
        private string name;
        private string skin;
        private List<Lane> lanes = new List<Lane>();

        internal List<PedestrianLight> PedestrianLights
        {
            get { return pedestrianLights; }
            set { pedestrianLights = value; }
        }
        public List<CarLight> CarLights
        {
            get { return carLights; }
            set { carLights = value; }
        }
        public List<Lane> Lanes
        {
            get { return lanes; }
            set { lanes = value; }
        }
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        public string Skin
        {
            get { return skin; }
            set { skin = value; }
        }

        public CarLight getCarLight(int index)
        {
            return carLights[index];
        }

        // Default constructor for serialization
        public Road()
        {

        }

        public void changeLights()
        {

        }

        public Road(string _name, string _skin, Directions direction)
        {
            name = _name;
            skin = _skin;
          //  Name = "crossing";
            System.Console.WriteLine("oszTy");

            if (name == "crossing")
            {
                System.Console.WriteLine("do chuja");
                invokeCarLights();
                // top road {0,1}
                lanes.Add(new Lane(Directions.South, false));
                lanes.Add(new Lane(Directions.North, true));

                // order of slots related to lane direction
                lanes[0].Slots.Add(new Slot(true, false, false));
                lanes[0].Slots.Add(new Slot(true, false, true)); // adjacent to crossing CarLights

                lanes[1].Slots.Add(new Slot(true, false, false));
                lanes[1].Slots.Add(new Slot(true, false, false));

                // right road {2,3}
                lanes.Add(new Lane(Directions.West, false));
                lanes.Add(new Lane(Directions.East, true));

                lanes[2].Slots.Add(new Slot(true, false, false));
                lanes[2].Slots.Add(new Slot(true, false, true));

                lanes[3].Slots.Add(new Slot(true, false, false));
                lanes[3].Slots.Add(new Slot(true, false, false));

                // bottom road {4,5}
                lanes.Add(new Lane(Directions.North, false));
                lanes.Add(new Lane(Directions.South, true));

                lanes[4].Slots.Add(new Slot(true, false, false));
                lanes[4].Slots.Add(new Slot(true, false, true));

                lanes[5].Slots.Add(new Slot(true, false, false));
                lanes[5].Slots.Add(new Slot(true, false, false));

                // left road {6,7}
                lanes.Add(new Lane(Directions.East, false));
                lanes.Add(new Lane(Directions.West, true));

                lanes[6].Slots.Add(new Slot(true, false, false));
                lanes[6].Slots.Add(new Slot(true, false, true));

                lanes[7].Slots.Add(new Slot(true, false, false));
                lanes[7].Slots.Add(new Slot(true, false, false));

                // center {8,9}
                lanes.Add(new Lane(Directions.West, false));
                lanes.Add(new Lane(Directions.East, false));

                lanes[8].Slots.Add(new Slot(true, false, false));
                lanes[8].Slots.Add(new Slot(true, false, false));

                lanes[9].Slots.Add(new Slot(true, false, false));
                lanes[9].Slots.Add(new Slot(true, false, false));
            }
            else if (name == "Tcrossing")
            {
                System.Console.WriteLine("do chuja");
                invokeCarLightsTcrossing();
                // top road {0,1}
                lanes.Add(new Lane(Directions.South, false));
                lanes.Add(new Lane(Directions.North, true));

                // order of slots related to lane direction
                lanes[0].Slots.Add(new Slot(true, false, false));
                lanes[0].Slots.Add(new Slot(true, false, true)); // adjacent to crossing CarLights

                lanes[1].Slots.Add(new Slot(true, false, false));
                lanes[1].Slots.Add(new Slot(true, false, false));

                // right road {2,3}
                lanes.Add(new Lane(Directions.West, false));
                lanes.Add(new Lane(Directions.East, true));

                lanes[2].Slots.Add(new Slot(true, false, false));
                lanes[2].Slots.Add(new Slot(true, false, true));

                lanes[3].Slots.Add(new Slot(true, false, false));
                lanes[3].Slots.Add(new Slot(true, false, false));

                // bottom road {4,5}
                lanes.Add(new Lane(Directions.North, false));
                lanes.Add(new Lane(Directions.South, true));

                lanes[4].Slots.Add(new Slot(true, false, false));
                lanes[4].Slots.Add(new Slot(true, false, true));

                lanes[5].Slots.Add(new Slot(true, false, false));
                lanes[5].Slots.Add(new Slot(true, false, false));

                // left road {6,7}
                lanes.Add(new Lane(Directions.East, false));
                lanes.Add(new Lane(Directions.West, true));

                lanes[6].Slots.Add(new Slot(true, false, false));
                lanes[6].Slots.Add(new Slot(true, false, true));

                lanes[7].Slots.Add(new Slot(true, false, false));
                lanes[7].Slots.Add(new Slot(true, false, false));

                // center {8,9}
                lanes.Add(new Lane(Directions.West, false));
                lanes.Add(new Lane(Directions.East, false));

                lanes[8].Slots.Add(new Slot(true, false, false));
                lanes[8].Slots.Add(new Slot(true, false, false));

                lanes[9].Slots.Add(new Slot(true, false, false));
                lanes[9].Slots.Add(new Slot(true, false, false));
            }
            else if (name == "straight")
            {
                Console.WriteLine("a tu?");
                if (direction == Directions.East || direction == Directions.West)
                {
                    lanes.Add(new Lane(Directions.West, true));
                    lanes.Add(new Lane(Directions.East, true));
                }
                else
                {
                    lanes.Add(new Lane(Directions.South, true));
                    lanes.Add(new Lane(Directions.North, true));
                }
                for (int i=0; i<6; i++)
                {
                    lanes[0].Slots.Add(new Slot(true, false, false));
                    lanes[1].Slots.Add(new Slot(true, false, false));
                }
            }
            else if (name == "corner")
            {
                Console.WriteLine("kurwa no co jest");
                lanes.Add(new Lane(Directions.South, false));
                lanes.Add(new Lane(Directions.North, false));

                lanes.Add(new Lane(Directions.West, false));
                lanes.Add(new Lane(Directions.East, false));

                lanes.Add(new Lane(Directions.North, false));
                lanes.Add(new Lane(Directions.South, false));

                lanes.Add(new Lane(Directions.East, false));
                lanes.Add(new Lane(Directions.West, false));

                lanes.Add(new Lane(Directions.West, false));
                lanes.Add(new Lane(Directions.East, false));

                lanes[8].Slots.Add(new Slot(true, false, false));
                lanes[8].Slots.Add(new Slot(true, false, false));

                lanes[9].Slots.Add(new Slot(true, false, false));
                lanes[9].Slots.Add(new Slot(true, false, false));

                if (direction == Directions.East)
                {
                    System.Console.WriteLine("East");
                    lanes[7].Exit = true;
                    lanes[1].Exit = true;

                    lanes[6].Slots.Add(new Slot(true, false, false));
                    lanes[6].Slots.Add(new Slot(true, false, false));

                    lanes[7].Slots.Add(new Slot(true, false, false));
                    lanes[7].Slots.Add(new Slot(true, false, false));

                    lanes[0].Slots.Add(new Slot(true, false, false));
                    lanes[0].Slots.Add(new Slot(true, false, false));

                    lanes[1].Slots.Add(new Slot(true, false, false));
                    lanes[1].Slots.Add(new Slot(true, false, false));
                }

                else if (direction == Directions.South)
                {
                    System.Console.WriteLine("South");
                    lanes[1].Exit = true;
                    lanes[3].Exit = true;

                    lanes[0].Slots.Add(new Slot(true, false, false));
                    lanes[0].Slots.Add(new Slot(true, false, false));

                    lanes[1].Slots.Add(new Slot(true, false, false));
                    lanes[1].Slots.Add(new Slot(true, false, false));

                    lanes[2].Slots.Add(new Slot(true, false, false));
                    lanes[2].Slots.Add(new Slot(true, false, false));

                    lanes[3].Slots.Add(new Slot(true, false, false));
                    lanes[3].Slots.Add(new Slot(true, false, false));
                }
                else if (direction == Directions.West)
                {
                    System.Console.WriteLine("West");
                    lanes[3].Exit = true;
                    lanes[5].Exit = true;

                    lanes[2].Slots.Add(new Slot(true, false, false));
                    lanes[2].Slots.Add(new Slot(true, false, false));

                    lanes[3].Slots.Add(new Slot(true, false, false));
                    lanes[3].Slots.Add(new Slot(true, false, false));

                    lanes[4].Slots.Add(new Slot(true, false, false));
                    lanes[4].Slots.Add(new Slot(true, false, false));

                    lanes[5].Slots.Add(new Slot(true, false, false));
                    lanes[5].Slots.Add(new Slot(true, false, false));
                }
                else if (direction == Directions.North)
                {
                    System.Console.WriteLine("North");
                    lanes[5].Exit = true;
                    lanes[7].Exit = true;

                    lanes[4].Slots.Add(new Slot(true, false, false));
                    lanes[4].Slots.Add(new Slot(true, false, false));

                    lanes[5].Slots.Add(new Slot(true, false, false));
                    lanes[5].Slots.Add(new Slot(true, false, false));

                    lanes[6].Slots.Add(new Slot(true, false, false));
                    lanes[6].Slots.Add(new Slot(true, false, false));

                    lanes[7].Slots.Add(new Slot(true, false, false));
                    lanes[7].Slots.Add(new Slot(true, false, false));
                }
            }

            if (name == "straight")
            {
                if (skin == "hor" || skin == "ver")
                {
                    List<int> inter = new List<int>();
                    inter.Add(500);
                    inter.Add(500);
                    if (skin == "hor") pedestrianLights.Add(new PedestrianLight(inter, Directions.East));
                    if (skin == "ver") pedestrianLights.Add(new PedestrianLight(inter, Directions.North));
                }
                if (skin == "both")
                {
                    List<int> inter = new List<int>();
                    inter.Add(500);
                    inter.Add(500);
                    pedestrianLights.Add(new PedestrianLight(inter, Directions.North));
                    pedestrianLights.Add(new PedestrianLight(inter, Directions.East));
                }
            }
        }
      //  public Road(string _name, string _skin, List<Lane> lanes)
       // {

//        }
        /*
        public void addCarLight(List<int> intervals, Directions direction)
        {
            CarLights.Add(new CarLight(intervals,direction));
        }
        public void createCarLight(CarLight _carCarLight)
        {
            CarLights.Add(_carCarLight);
        }
         * */
       
        private void invokeCarLights()
        {
            carLights = new List<CarLight>();
            List<int> intervals = new List<int>();
            intervals.Add(2500);
            intervals.Add(2500);
            intervals.Add(1000);
            carLights.Add(new CarLight(intervals, Directions.North));
            carLights.Add(new CarLight(intervals, Directions.East));
            carLights.Add(new CarLight(intervals, Directions.South));
            carLights.Add(new CarLight(intervals, Directions.West));
            System.Console.WriteLine("do chuja");
        }
        private void invokeCarLightsTcrossing()
        {
            carLights = new List<CarLight>();
            List<int> intervals = new List<int>();
            intervals.Add(2500);
            intervals.Add(2500);
            intervals.Add(1000);
            carLights.Add(new CarLight(intervals, Directions.North));
            carLights.Add(new CarLight(intervals, Directions.East));
            carLights.Add(new CarLight(intervals, Directions.South));
            System.Console.WriteLine("do chuja");
        }

        #region Serialize
        public Road(SerializationInfo info, StreamingContext ctxt)
        {
            this.carLights = (List<CarLight>)info.GetValue("CarLights", typeof(List<CarLight>));
            this.pedestrianLights = (List<PedestrianLight>)info.GetValue("PedestrianLight", typeof(List<PedestrianLight>));
            this.name = (string)info.GetValue("Name", typeof(string));
            this.skin = (string)info.GetValue("Skin", typeof(string));
            this.lanes = (List<Lane>)info.GetValue("Lanes", typeof(List<Lane>));
        }

        public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
        {
            info.AddValue("CarLights", this.carLights);
            info.AddValue("PedestrianLight", this.pedestrianLights);
            info.AddValue("Name", this.name);
            info.AddValue("Skin", this.skin);
            info.AddValue("Lanes", this.lanes);
        }
        #endregion
    }

    
}
